package com.zhuangjie.rider.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuangjie.base.entity.DateTimeRange;
import com.zhuangjie.rider.entity.RiderAsset;
import com.zhuangjie.rider.entity.RiderMoneyRecord;
import com.zhuangjie.rider.enums.AccountingStatusEnum;
import com.zhuangjie.rider.lock.RiderAssetLock;
import com.zhuangjie.rider.mapper.RiderMoneyRecordMapper;
import com.zhuangjie.rider.pojo.RiderAssetForPlus;
import com.zhuangjie.rider.service.RiderAssetService;
import com.zhuangjie.rider.service.RiderMoneyRecordService;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 收益进出账记录表 服务实现类
 * </p>
 *
 * @author zhuangjie
 * @since 2024-04-02
 */
@Service
public class RiderMoneyRecordServiceImpl extends ServiceImpl<RiderMoneyRecordMapper, RiderMoneyRecord> implements RiderMoneyRecordService {


    @Autowired
    private RiderAssetService riderAssetService;

    @Autowired
    private Redisson redisson;

    @Override
    public List<Long> queryDueBillRecord(DateTimeRange processDateTimeRange, Integer maxProcessingQuantity) {
        return this.baseMapper.queryDueBillRecord(processDateTimeRange,maxProcessingQuantity, AccountingStatusEnum.WAITING_FOR_ACCOUNTING.getCode());
    }

    @Transactional
    @Override
    public void moneyRecordAccounting(Long dueBillRecordId) {
        // 尝试将到账记录修改已结算状态
        boolean isUpdateSuccess = this.update(Wrappers.lambdaUpdate(RiderMoneyRecord.class)
                .eq(RiderMoneyRecord::getId, dueBillRecordId)
                .eq(RiderMoneyRecord::getStatus, AccountingStatusEnum.WAITING_FOR_ACCOUNTING.getCode())
                .set(RiderMoneyRecord::getStatus, AccountingStatusEnum.ACCOUNTED.getCode()));
        if (!isUpdateSuccess) return;
        // 更新成功，那么就进行结算，将钱打到骑手账户
        // 查询记录需要打款金额
        RiderMoneyRecord riderMoneyRecord = this.getById(dueBillRecordId);
        // 构建plus对象
        RiderAssetForPlus riderAssetForPlus = new RiderAssetForPlus();
        riderAssetForPlus.setPlusWalletAmount(riderMoneyRecord.getOperationAmount());
        riderAssetForPlus.setRiderId(riderMoneyRecord.getRiderId());
        plusRiderAsset(riderAssetForPlus);
    }


    /**
     * plus资产方法
     *  如plus积分、plus钱包金额
     * @param riderAssetForPlus
     */
    public void plusRiderAsset(RiderAssetForPlus riderAssetForPlus) {
        RLock lock = redisson.getLock(RiderAssetLock.getRiderAssetOperationLock(riderAssetForPlus.getRiderId()));
        try {
            lock.lock();
            int update = riderAssetService.plusUpdate(riderAssetForPlus);
            if (update == 0) {
                // 更新失败，可能还没有记录，先查询进行添加
                long count = riderAssetService.count(Wrappers.lambdaQuery(RiderAsset.class).eq(RiderAsset::getRiderId, riderAssetForPlus.getRiderId()));
                if (count == 0) {
                    RiderAsset riderAsset = new RiderAsset();
                    riderAsset.setRiderId(riderAssetForPlus.getRiderId());
                    riderAsset.setMargin(riderAssetForPlus.getPlusMargin());
                    riderAsset.setWalletAmount(riderAssetForPlus.getPlusWalletAmount());
                    riderAssetService.save(riderAsset);
                }
            }
        }finally {
            lock.unlock();
        }

    }

}
